package mya_dc.compilation_server.users;

import mya_dc.shared_classes.*;
import mya_dc.shared_classes.files_manipulation.*;
import mya_dc.shared_classes.Message.EMessageType;
import mya_dc.compilation_server.CompilationServer;
import mya_dc.compilation_server.database.*;

import java.io.File;
import java.sql.*;
import java.util.ArrayList;
import java.util.Iterator;


public class UserProjectManager 
{	
	/**
	 * Registers a new user to the server.
	 *
	 * @param	MessageObj  - A MYA_Authentication object.
	 * @param 	Transmitter - Tramsmitter for communication with the user being added.
	 */
	
	public static synchronized boolean addNewUserProject(Object MessageObj, Transmitter CurrTransmitter)
	{
		try
		{
			//check that there's enough room on the server to host the new project
			CurrTransmitter.send(new Message(EMessageType.LOGIN_NEW_PROJECT_SIZE,null));
			Message ProjectSize = CurrTransmitter.receive();	
	  		File tmpFile = new File(CurrTransmitter.getWorkingDirectory());
	  		Long Size = (Long)ProjectSize.getObject();
	  		if (tmpFile.getUsableSpace() - Size <= CompilationServer.getFreeSpaceMinimum())
	  		{
	  		  		Message ErrorMessage = new Message(EMessageType.LOGIN_FAILED_OUT_OF_SPACE,null);
					CurrTransmitter.send(ErrorMessage);
					return false;
	  		}
	  		//add new user to the database
	  		MYA_Authentication RequestedAuthentication =  (MYA_Authentication)MessageObj;
	  		Timestamp CurrTime = new Timestamp(new java.util.Date().getTime());
			DatabaseManager.addProjectEntry(RequestedAuthentication.getProject(), 
					                        RequestedAuthentication.getUserName(), 
					                        Size, 
					                        CurrTime);
	  		CurrTransmitter.send(new Message(EMessageType.SUCCESS,null));
	  		return true;
		}
		catch(Exception e)
		{
			return false;
		}
	}
	
	
	/**
	 * Deletes all of the project in the list from the server.
	 *
	 * @param	UserProjectList -  ArrayList of UserProject objects, containing the projects to be removed.
	 * @param 	sRootDirectory - Path to the root working directory of the server.
	 */
	public static synchronized void removeUsersProjects(ArrayList<UserProject> UserProjectList, String sRootDirectory)
	{
    	for (Iterator<UserProject> ListIterator = UserProjectList.iterator(); ListIterator.hasNext();)
    	{
    		UserProject CurrProject = ListIterator.next();
    		deleteProject(sRootDirectory,CurrProject.m_sUserName, CurrProject.m_sProjectName);
    	}
	}
	
	/**
	 * Deletes the project from the server.
	 * If the user has no remaining projects, the user's directories will be deleted as well.
	 *
	 * @param   sRootDirectory - Path to the root working directory of the server.
	 * @param	sUserName - User name.
	 * @param 	sProjectName - Project name.
	 */
	public static synchronized void deleteProject(String RootDirectory, String sUserName,String sProjectName) 
	{
		StringBuilder sbUsersSrcDir = new StringBuilder(RootDirectory + "projects\\sources\\" + sUserName);
		StringBuilder sbUserWorkDir = new StringBuilder(RootDirectory + "projects\\compilation\\" + sUserName);
		if (DatabaseManager.removeProjectEntry(sUserName,sProjectName) != 0) 
		{
			String ProjDir = "\\" + sProjectName;
			sbUsersSrcDir.append(ProjDir);
			sbUserWorkDir.append(ProjDir);
		}
		File fPathToDir = new File(sbUsersSrcDir.toString() );
		FileObject.deleteDirectory(fPathToDir);
		fPathToDir =  new File(sbUserWorkDir.toString());
		FileObject.deleteDirectory(fPathToDir);
	}
	
	/**
	 * Adds a user to the active users list.
	 *
	 * @param	sUserName - User name.
	 * @param 	sProjectName - Project name.
	 */
	public void addConnectedUser(String sUserName, String sProjectName)
	{
		UserProject NewUser = new UserProject(sUserName,sProjectName);
		if (m_ConnectedUsersArray.contains(NewUser))
		{
			return;
		}
		m_ConnectedUsersArray.add(NewUser);
	}
	
	
	/**
	 * Removes a user from the active users list.
	 *
	 * @param	sUserName - User name.
	 * @param 	sProjectName - Project name.
	 */
	public void removeConnectedUser(String sUserName, String sProjectName)
	{
		UserProject CurrUser = new UserProject(sUserName,sProjectName);
		m_ConnectedUsersArray.remove(CurrUser);
	}
	
	/**
	 * Checks if the user currently connected to the server.
	 *
	 * @param	sUserName - User name.
	 * @param 	sProjectName - Project name.
	 */
	public boolean isUserConnected(String sUserName, String sProjectName)
	{
		UserProject CurrUser = new UserProject(sUserName,sProjectName);
		return m_ConnectedUsersArray.contains(CurrUser);
	}
	

	private ArrayList<UserProject> m_ConnectedUsersArray = new ArrayList<UserProject>(500);
	
}
